package com.effective.java.equals;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;

public class BrokenLiskovSubstitutionPrinciple01 {

	public static void main(String[] args) {

		Point p1 = new Point(1, 0);
		Point p2 = new Point(0, 1);
		Point p3 = new Point(-1, 0);
		Point p4 = new Point(0, -1);

		List<Point> circle = new ArrayList<Point>();
		circle.add(p1);
		circle.add(p2);
		circle.add(p3);
		circle.add(p4);

		System.out.println("circle.contains(p1) = " + circle.contains(new Point(1, 0)));
		System.out.println("circle.contains(p2) = " + circle.contains(new Point(0, 1)));
		System.out.println("circle.contains(p3) = " + circle.contains(new ColorPoint(-1, 0, Color.BLUE)));
		System.out.println("circle.contains(p4) = " + circle.contains(new Point(0, -1)));
	}

	private static class Point {

		private final int x;
		private final int y;

		public Point(int x, int y) {

			this.x = x;
			this.y = y;
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public boolean equals(Object object) {

			/*
			 * This breaks the liskov substitution principle that says that any
			 * property of a type should also hold for its subtypes
			 */
			if (object == null || object.getClass() != this.getClass()) {
				return false;
			}

			Point p = (Point) object;
			return p.x == this.x && p.y == this.y;
		}

	}

	private static class ColorPoint extends Point {

		@SuppressWarnings("unused")
		private final Color color;

		public ColorPoint(int x, int y, Color color) {

			super(x, y);
			this.color = color;
		}
	}
}
